import logging
import re

from random import randint

from django.db.models import Prefetch
from django_redis import get_redis_connection
from rest_framework import status
from rest_framework.permissions import IsAuthenticated
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.generics import CreateAPIView, RetrieveUpdateAPIView, RetrieveAPIView, UpdateAPIView, GenericAPIView

from mlh.utils.image_storage import storage
from users.serializers import UserFileRetrieveUpdateSerializer, UserBasicSerializer, ExperienceSerializer
from . import constants, serializers
from .models import User, Experience
from mlh.utils.yuntongxun.sms import CCP
# from mlh.utils.yuntongxun.sms import CCP

logger = logging.getLogger('django')
# 用户名称判断
# 1 后端接口设计 请求方式 GET
# 2 路由 usernames/(?P<username>\w{5,20})/count/
# 3 返回参数 用户名 & 当前用户名在数据库中的数量
# { "username":"zhangsan", "count":1 }
class UserNameView(APIView):
    """用户名已注册验证"""

    def get(self, request, username):
        """校验用户名是否已存在"""
        count = User.objects.filter(username=username).count()
        data = {
            "username": username,
            "count": count
        }

        return Response(data)


# 手机号判断
# 1 后端接口设计 请求方式 GET
# 2 路由 mobiles/(?P<mobile>1[3-9]\d{9})/count
# 3 返回参数 手机号 & 当前手机号在数据库中的数量
# { "mobile":"13811111111", "count":1 }
class MobileView(APIView):
    """手机号已注册验证"""

    def get(self, request, mobile):
        """校验手机号是否已存在"""
        count = User.objects.filter(mobile=mobile).count()
        data = {
            "mobile": mobile,
            "count": count
        }

        return Response(data)


# 发送短信
# 1 后端接口设计 请求方式 GET
# 2 路由 sms_code/(?P<mobile>1[3-9]\d{9})/
# 3 返回参数 提示信息 --> 成功 OK  不成功 FAILED
# { "message":"OK" }
class SMSCodeView(APIView):
    """短信验证码"""

    # 请求方式 GET 传入参数 mobile
    def get(self, request, mobile):
        """生成短信验证码"""

        if not re.match(r'^1[3-9]\d{9}$', mobile):
            return Response({"message": "手机号格式错误"}, status=status.HTTP_400_BAD_REQUEST)

        redis_conn = get_redis_connection("verify_codes")
        send_flag = redis_conn.get("send_flag_%s" % mobile)
        if send_flag:
            return Response({"message": "请求过于频繁，请稍后再试"}, status=status.HTTP_400_BAD_REQUEST)
        # 随机生成6位数字验验码
        sms_code = "%06d" % randint(0, 999999)
        print("\n========短信验证码:%s========\n" % sms_code)  # 控制台测试

        # 将生成的校验码保存在redis中，并设置保存flag  smscode保存类型 string  {"sms_mobile":"smscode"}
        #                                         flag保存类型 string  {"send_flag_mobile":"1"}
        pl = redis_conn.pipeline()
        pl.setex("sms_%s" % mobile, constants.SMS_CODE_REDIS_EXPIRES, sms_code)
        pl.setex("send_flag_%s" % mobile, constants.SEND_SMS_CODE_FLAG, 1)
        pl.execute()

        # 发送短信验证码
        # SMS_CODE_EXPIRES = constants.SMS_CODE_REDIS_EXPIRES // 60
        # ccp = CCP()
        # ccp.send_template_sms(mobile, [sms_code, SMS_CODE_EXPIRES], constants.SMS_TEMPLATE_ID)

        return Response({"message": "OK"})


# 前端提交注册信息
# 后端设计 请求方式 POST
# 路由 users/
# 返回前端的内容 {'id':user.id, 'username':username, 'mobile':mobile}
class UserRegisterView(CreateAPIView):
    """用户注册信息"""
    # 将校验，保存全放到 序列化器中处理
    serializer_class = serializers.UserRegisterSerializer


# 头像上传
class pic_info(APIView):

    permission_classes = [IsAuthenticated]

    def get(self,request):
        user = request.user
        head_portrait_url = User.objects.get(id=user.id).head_portrait
        return Response({'head_portrait_url': head_portrait_url})

    def post(self, request):
        user = request.user

        # 获取上传文件
        try:
            por_file = request.data['img']
        except Exception as e:
            logging.error(e)
            return Response({"message": "上传图片参数错误"}, status=status.HTTP_400_BAD_REQUEST)
        url = storage(por_file)
        user.head_portrait = url
        try:
            user.save()
        except Exception as e:
            logging.error(e)
            return Response({"message": "保存数据失败"}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
        return_dict = {"head_portrait_url": url}
        return Response(return_dict)


# 个人档案
class UserFileView(RetrieveAPIView):
    # permission_classes = [IsAuthenticated]
    # queryset = User.objects.all().prefetch_related(Prefetch('experience_set', Experience.objects.all().filter(type=1), 'work'),
    queryset = User.objects.all().prefetch_related(Prefetch('experience_set', Experience.objects.all().filter(type=1), 'works'),
                                                   Prefetch('experience_set', Experience.objects.all().filter(type=2), 'educations'))
    serializer_class = UserFileRetrieveUpdateSerializer


class UserBasicView(UpdateAPIView):
    # permission_classes = [IsAuthenticated]
    queryset = User.objects.all()
    serializer_class = UserBasicSerializer

    def patch(self, request, *args, **kwargs):
        user = self.get_object()
        serializer = self.get_serializer(user, data=request.data, partial=True)
        if serializer.is_valid():
            serializer.save()
            return Response(data=serializer.data, status=status.HTTP_200_OK)
        return Response(data="wrong parameters", status=status.HTTP_400_BAD_REQUEST)


class ExperienceView(UpdateAPIView):
    # queryset = Experience.objects.all()
    serializer_class = ExperienceSerializer

    def get_object(self):
        return Experience.objects.get(id=self.kwargs['pk'])

    def patch(self, request, *args, **kwargs):
        experience = self.get_object()
        serializer = self.get_serializer(experience, data=request.data, partial=True)
        if serializer.is_valid():
            serializer.save()
            return Response(data=serializer.data, status=status.HTTP_200_OK)
        return Response(data="wrong parameters", status=status.HTTP_400_BAD_REQUEST)

